package eclipse.lib.graphics;
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.ImageIO;
import javax.media.opengl.GL;
import javax.swing.ImageIcon;
import com.sun.opengl.util.texture.*;
import eclipse.ErrorManager;
/**
 * The TextureLoader class takes the path of a texture and loads/streams it for use in the Application.
 */
/*
 * Copyright (c) 2009, TOD Productions All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 *	- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 *	- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 *	-Neither the name of the organization nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */
public final class GLTextureLoader
{
	/**
	 * Loads an image from an Input stream using specified extension
	 * @param iFile InputStream of the image
	 * @param mipmap use mipmaps
	 * @param ext String extension
	 */
	public static final Texture loadIMG(InputStream iFile, boolean mipmap, String ext)
	{
		final Texture text;
		try
		{
			BufferedImage bImg = makeBufferedImage(makeImage(iFile));
			bImg = processBufferedImage(bImg);
            text = TextureIO.newTexture(bImg, mipmap);        
			text.setTexParameteri(GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
			text.setTexParameteri(GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
			return text;
		}
		catch(Exception e)
		{
			System.out.println(e.toString());
			return null;
		}		
	}	
	public static final Texture loadUnprocessedIMG(InputStream iFile, boolean mipmap, String ext)
	{
		final Texture text;
		try
		{
			text = TextureIO.newTexture(iFile, mipmap, ext);
			return text;
		}
		catch(Exception e)
		{
			ErrorManager.handleError(e);
			return null;
		}
	}
    // This method returns a buffered image with the contents of an image
    public static final BufferedImage makeBufferedImage(Image image) 
    {          
        // This code ensures that all the pixels in the image are loaded
        image = new ImageIcon(image).getImage();
    
        // Determine if the image has transparent pixels; for this method's
        // implementation, see e661 Determining If an Image Has Transparent Pixels
        final boolean hasAlpha = hasAlpha(image);
        if (image instanceof BufferedImage)
        {
        	if(hasAlpha)
        		return (BufferedImage)image;
        }
        // Create a buffered image with a format that's compatible with the screen
        BufferedImage bimage = null;
        final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        try {
        	
            // Determine the type of transparency of the new buffered image
            final int transparency = Transparency.TRANSLUCENT;
            
    
            // Create the buffered image
            final GraphicsDevice gs = ge.getDefaultScreenDevice();
            final GraphicsConfiguration gc = gs.getDefaultConfiguration();
            bimage = gc.createCompatibleImage(
                image.getWidth(null), image.getHeight(null), transparency);
        } catch (Exception e) {
            // The system does not have a screen
        }
    
        if (bimage == null) {
            // Create a buffered image using the default color model
            int type = BufferedImage.TYPE_INT_RGB;
            if (hasAlpha)
                type = BufferedImage.TYPE_INT_ARGB;
            bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
        }
    
        // Copy image to buffered image
        final Graphics g = bimage.createGraphics();
    
        // Paint the image onto the buffered image
        g.drawImage(image, 0, 0, null);
        g.dispose();
    
        return bimage;
    }
    public static final boolean hasAlpha(Image image) {
        // If buffered image, the color model is readily available
        if (image instanceof BufferedImage) {
            final BufferedImage bimage = (BufferedImage)image;
            return bimage.getColorModel().hasAlpha();
        }
    
        // Use a pixel grabber to retrieve the image's color model;
        // grabbing a single pixel is usually sufficient
        final PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
        try {
            pg.grabPixels();
        } catch (InterruptedException e) {
        }
    
        // Get the image's color model
        final ColorModel cm = pg.getColorModel();
        return cm.hasAlpha();
    }
    public static final Image makeImage(InputStream iFile)
    {    	
    	final Image image;		
    	try
    	{
    		image = ImageIO.read(iFile);
    	}
		catch(Exception e)
		{
			ErrorManager.handleError(e);
			return null;
		}
    	return image;
    }
    public static final BufferedImage processBufferedImage(BufferedImage bImage)
    {
    	int x, y, p, filterColor;
    	
    	x = bImage.getWidth();
    	y = bImage.getHeight();
    	Color color, mColor;
    	filterColor = bImage.getRGB(0,0);
    	for(int x1 = 0; x1 < x; x1++)
    	{
    		for(int y1 = 0; y1 < y; y1++)
    		{
    			p = bImage.getRGB(x1, y1);    			
    			color = new Color(p);   
    			if(p == filterColor)
    				mColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), 0);    			
    			else
    				mColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());    			
    			bImage.setRGB(x1, y1, mColor.getRGB());    	
    		}
    	}    	
    	return bImage;
    }
}
